﻿using System.Collections.Generic;
using GameFramework;
using GameFramework.Event;
using UnityEngine;
using UnityGameFramework.Runtime;

namespace StarForce
{
    public class SurvivalGame : GameBase
    {
        public override GameMode GameMode
        {
            get { return GameMode.Survival; }
        }
        
        /// <summary>
        /// 难度等级
        /// </summary>
        private int m_Level;
        
        /// <summary>
        /// 创建地板类
        /// </summary>
        private ICreateGround m_CreateGround;

        /// <summary>
        /// 当前使用的地板创建类
        /// </summary>
        public ICreateGround m_CurrentCreateGround
        {
            get;
            private set;
        }
        
        /// <summary>
        /// 初始地板生成位置
        /// </summary>
        private float m_GroundStartLocationY = -3f;
        
        private float m_GroundCurLocationY = -3f;

        /// <summary>
        /// 地板之间的距离
        /// </summary>
        private float m_GroundLocationAddY = 2f;
        
        /// <summary>
        /// 分数记录
        /// </summary>
        private int m_Score;
        

        /// <summary>
        /// 字典存储不同等级 生成不同的地板
        /// </summary>
        private Dictionary<int, ICreateGround> m_CreateGrounds = new Dictionary<int, ICreateGround>();

        private CreateGroundManager m_GroundManager;
        
        public override void Initialize()
        {
            base.Initialize();
            m_GroundManager = new CreateGroundManager();
            GameEntry.Event.Subscribe(CreateNewGroundEventArgs.EventId,OnCreateNewGround);
            GameEntry.Event.Subscribe(RestartGameEventGame.EventId,OnRestartGame);
            GameEntry.Event.Subscribe(UpScoreEventArgs.EventId,OnUpScore);
            m_CreateGrounds.Add(0,new CreateNormalGround());
            m_CreateGrounds.Add(1,new CreateComposeGround());
            m_CreateGrounds.Add(2,new CreatePropGround());
            m_Score = 0;
            SetLevel();
            PreLoad();
        }

        public override void Update(float elapseSeconds, float realElapseSeconds)
        {
            base.Update(elapseSeconds, realElapseSeconds);
        }

        public override void Shutdown()
        {
            base.Shutdown();
            m_CreateGrounds.Clear();
            GameEntry.Event.Unsubscribe(CreateNewGroundEventArgs.EventId,OnCreateNewGround);
            GameEntry.Event.Unsubscribe(RestartGameEventGame.EventId,OnRestartGame);
            GameEntry.Event.Unsubscribe(UpScoreEventArgs.EventId,OnUpScore);
        }
        
        /// <summary>
        /// 设置具体创建工厂类
        /// </summary>
        /// <param name="createGround"></param>
        /// <exception cref="GameFrameworkException"></exception>
        public void SetCreateGround(ICreateGround createGround)
        {
            if (createGround == null)
            {
                throw new GameFrameworkException("ICreateGround is valid");
            }

            m_CreateGround = createGround;  
        }
        public void SetLevel()
        {
            //todo 计算分数
            if (m_Score<100)
            {
                m_Level = 0;
            }
            else if(m_Score<300)
            {
                m_Level = 1;
            }
            else
            {
                m_Level = 2;
            }

            ICreateGround createGround;
            if (!m_CreateGrounds.TryGetValue(m_Level,out createGround))
            {
                throw new GameFrameworkException("createGround is Valid");
            }
            SetCreateGround(createGround);
        }

        private void OnRestartGame(object sender, GameEventArgs e)
        {
            Clear();
            PreLoad();
        }

        private void OnCreateNewGround(object sender, GameEventArgs e)
        {
            CreateGround();  
        }

        /// <summary>
        /// 加载游戏资源
        /// </summary>
        private void PreLoad()
        {
            //加载player
            GameEntry.Entity.ShowPlayer(new PlayerData(GameEntry.Entity.GenerateSerialId(), 1, Vector3.forward));

            //初始位置的Ground
            m_GroundManager.LoadGround(new Vector3(0, -3, 1), GroundType.Normal);
            GameEntry.Entity.ShowDeathGround(new DeathGroundData(GameEntry.Entity.GenerateSerialId(), 3,
                new Vector3(0, -5.5f, 1), (int) GroundType.DeathGround));

            for (int i = 0; i < 3; i++)
            {
                CreateGround();
            }
        }
        
        
        private void CreateGround()
        {
            if (m_CreateGround == null)
            {
                throw new GameFrameworkException("ICreateGround is valid");
            }
            //todo 生成数量
            int createNum = 2;
           
            for (int i = 0; i < createNum; i++)
            {
                GroundDataList groundDatas = m_CreateGround.GetCreateGroundDatas();
                float locationY = GetGroundNextLocation();
                foreach (CreateGroundData data in groundDatas)
                {
                    m_GroundManager.LoadGround(new Vector3(data.GroundLocation,locationY,1),  data.GroundType);
                    if (data.HasProp)
                    {
                        m_GroundManager.LoadProp(new Vector3(data.GroundLocation,locationY+2f,1));
                    }
                }
            }
        }
        private void OnUpScore(object sender, GameEventArgs e)
        {
            UpScoreEventArgs result = (UpScoreEventArgs) e;
            m_Score += result.Score;
            SetLevel();
        }
        
        /// <summary>
        /// 获取到下一个地板生成位置
        /// </summary>
        /// <returns></returns>
        public float GetGroundNextLocation()
        {
            m_GroundCurLocationY += m_GroundLocationAddY;
            return m_GroundCurLocationY;
        }
        
        
        public void Clear()
        {
            //清空数据
            m_Score = 0;
            SetLevel();
            m_GroundCurLocationY = m_GroundStartLocationY;
        }

    }
}